package vkontakte
{
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    
    import json.JParser;
    
    public class VKontakteAPI
    {
        // application secret key
        private static const APP_SECRET : String = "cSubEcp6q3";

        // stored application id to use when running locally
        private static var API_ID    : String = "1628882";
        // stored user id to use when running locally
        private static var UID       : String = "52531344";
        // test mode for running in sandbox mode
        // replace by "0" after switching application to public access
        private static var TEST_MODE : String = "1";

        ///////////////////////////////////
        // private utility functions
        ///////////////////////////////////
        
        // return array of values included in all requests
        private static function getBaseValues() : Array
        {
            return [
                "api_id=" + API_ID,
                "v=2.0",
                "format=json",
                "test_mode=" + TEST_MODE
            ];
        }
        
        // returns MD5 as required by vKontakte API
        private static function getMD5(values : Array) : String
        {
            // sort values alphabetically
            values.sort();
            
            var hash_str : String = "";            
            hash_str += UID;
            for(var i : int = 0; i < values.length; i++)
                hash_str += values[i];
            hash_str += APP_SECRET;
            
            return MD5.hex_md5(hash_str); 
        }
        
        // combine request string
        private static function getRequestString(values : Array) : String
        {
            var request : String = "http://api.vkontakte.ru/api.php";
            for(var i : int = 0; i < values.length; i++)
                request += (i == 0 ? "?" : "&") + values[i];
            return request;
        }
        
        // main request function
        // method - vKontakteAPI method name (like "getUserInfo" or "getProfiles")
        // add_values - addition method parameters (ex. for "getProfiles"
        //     add_values must contain list of uids like "uids=123,3124,3123")
        // callback - function called after completing request 
        private static function makeRequest(method : String, add_values : String, callback : Function) : void
        {
            // base values for all requests
            var values : Array = getBaseValues();
            // add method name
            values.push("method=" + method);
            // add additional values if have any
            if(add_values)
                values.push(add_values);
            // calculate md5 hash and add it to values array
            values.push("sig=" + getMD5(values));
            
            // request loader
            var loader : URLLoader  = new URLLoader();
            // register listener for COMPLETE event
            loader.addEventListener(
                Event.COMPLETE,
                function (event : Event) : void  
                {
                    // extract loader from event
                    var loader : URLLoader = URLLoader(event.target);
                    // parse json data and pass it
                    // to callback function
                    callback(JParser.decode(loader.data));
                });
            // fire request with url created from values 
            loader.load(new URLRequest(getRequestString(values)));
        }
        
        ///////////////////////////////////
        // public functions
        ///////////////////////////////////
        
        // getter for current user id
        public static function get uid() : String { return UID; }
 
         // must be called at application start
        // to init API variables (or left default values when running locally)
        public static function init(flashvars : Object) : void
        {
            // if have viewer_id in flashvars
            if(flashvars.viewer_id)
            {
                // then it means that application started in vKontakte framework
                // update userID for user whos started application
                UID  = flashvars.viewer_id;
            }
        }
       
        // get basic user(s) data (uid, first_name, last_name) for provided uids array
        public static function getProfiles(uids : Array, callback : Function) : void
        {
            var uids_str : String = "uids=" + uids[0];
            for(var i : int = 1; i < uids.length; i++)
                uids_str += "," + uids[i];
            makeRequest("getProfiles", uids_str, callback);
        }
        
        // returns friends of the current user
        public static function getFriends(callback : Function) : void
        {
            makeRequest("getFriends", null, callback);
        }
        
        // stores user score on vKontakte database
        public static function setUserScore(score : Number, callback : Function) : void
        {
            makeRequest("setUserScore", "score=" + String(score), callback);
        }
        
        // retreive leaderboard from vKontakte database
        public static function getHighScores(callback : Function) : void
        {
            makeRequest("getHighScores", null, callback);
        }
    }
}